import { Transaction } from "tiny-entity2";
import { IQueryObject } from "tiny-entity2/queryObject";
import { ApiDataContext } from "../domain/apiDataContext";
import { Menu } from "../domain/models/menu";
import { Page } from "../domain/models/page";
import { BaseService, QueryParamsBase } from "./baseService";

export class MenuService extends BaseService {
    CreateMenu(entity: Menu, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new Menu();
            d.ConverToEntity(entity);
            let obj: Page = await ctx.Page.First(x => x.id == $args1, { $args1: d.pageId });
            if (obj) {
                d.pageName = obj.name;
            }
            return ctx.Create(d);
        });
    }
    UpdateMenu(entity: Menu, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new Menu();
            d.ConverToEntity(entity);
            // let obj: Page = await ctx.Page.First(x => x.id == $args1, { $args1: d.pageId });
            // if (obj) {
            //     d.pageName = obj.name;
            // }

            return ctx.Update(d);
        });
    }
    UpdateMenuIndex(entity: Menu, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new Menu();
            d.ConverToEntity(entity);

            // let excludeKeys = Object.keys(d).filter(x => {
            //     if (x == 'id') {
            //         return false;
            //     }
            //     if (x == 'index') {
            //         return false;
            //     }
            // });


            return ctx.Query(`UPDATE menu SET \`index\` = ${d.index}  Where id='${d.id}'`);
        });
    }

    async GetMenuById(id: string) {
        let ctx = new ApiDataContext();
        return ctx.Menu.First(x => x.id == $args1, { $args1: id });
    }
    async QueryMenu(params) {
        let q = await this.GetQueryCtx(params);
        let total = await q.Count();

        let q2 = await this.GetQueryCtx(params);
        if (params.countOfPage && params.pageIndex) {
            q2 = q2.Take(params.countOfPage).Skip(params.pageIndex - 1) as any;
        }
        let list = await q2.OrderBy(x => x.index).ToList();

        return {
            total,
            list
        };
    }

    private async GetQueryCtx(params: MenuQueryParams) {
        let ctx = new ApiDataContext();
        let q = ctx.Menu as IQueryObject<Menu>;
        q = q.Where(x => x.isDelete == $args1, { $args1: false });
        if (params) {
            if (params.name) {
                q = q.Where(x => x.name.indexOf($args1), { $args1: params.name });
            }
            if (params.orgId) {
                q = q.Where(x => x.orgId == $args1 || x.orgId == 'global', { $args1: params.orgId });
            }
            if (params.parentId) {
                q = q.Where(x => x.parentId == $args1, { $args1: params.parentId });
            }
        }
        return q;
    }

    DeleteMenuById(menuId: string, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            return ctx.Delete<Menu>(x => x.id == $args1, ctx.Menu, {
                $args1: menuId
            });
        });
    }
}

export interface MenuQueryParams extends QueryParamsBase {
    name?: string;
    parentId?: string;
    orgId?: string;
}